/*
 * Copyright 2007 Jeffrey Palm
 */

import java.io.*;
import java.util.*;

abstract class FileSink extends AbstractSink {

  private final File outdir;

  FileSink(File outdir) {
    this.outdir = mkdir(outdir,name());
  }

  final void prepare() {
    if (outdir != null) outdir.mkdirs();
    prepareRest();
  }

  final void postpare() {
    postpareRest();
  }

  /** Override this */
  void prepareRest() {}

  /** Override this */
  void postpareRest() {}
  
  // --------------------------------------------------
  // Abstract
  // --------------------------------------------------

  /**
   * @return the file name for a given type
   */
  abstract String getFileName(World.Type t);
  
  /**
   * Output the world to <tt>out</tt>
   */
  abstract void output(World.Type t, PrintStream out) throws Exception;
  
  /**
   * @return the name used for the subdirectory of the output dir
   */
  abstract String name();

  protected final File getOutdir() {return outdir;}

  private File mkdir(File d, String s) {
    File res = new File(d,s);
    res.mkdirs();
    return res;
  }

  private File newFile(File dir, String name) {
    File res = new File(dir,name);
    fileNames.add(name);
    files.add(res);
    return res;
  }

  private final List<String> fileNames = new ArrayList<String>();
  private final List<File> files = new ArrayList<File>();

  protected final List<String> getFileNames() {return fileNames;}
  protected final List<File> getFiles() {return files;}
  
  final void output(World.Type t) throws Exception {
    PrintStream out = outdir == null 
      ? System.out 
      : new PrintStream(new FileOutputStream(newFile(outdir,getFileName(t))));
    output(t,out);
    if (out != System.out) out.close();
  }
}